package apputil

import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"

	"gopkg.in/ini.v1"
	"gorm.io/gorm"

	Log "github.com/cihub/seelog"
	"github.com/gin-gonic/gin"

	"gitee.com/tomatomeatman/golang-repository/bricks3/function/configutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/function/data/aesutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/function/data/stringutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/cloud"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/ginutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/gormutil"
)

func Run(interceptorFunc func(ctx *gin.Context) bool, dbOpenFun func(dsn string) gorm.Dialector) {
	configFile := "./config/app.ini"

	go initMainDb(configFile, dbOpenFun) // 初始化主数据库

	Title := configutil.ReadConfigKey(configFile, "System", "Title", "").(string)
	Name := configutil.ReadConfigKey(configFile, "System", "Name", "").(string)
	appKey := configutil.ReadConfigKey(configFile, "System", "AppKey", "").(string)
	Root := configutil.ReadConfigKey(configFile, "System", "Root", "/webroot/").(string)
	Port := configutil.ReadConfigKey(configFile, "System", "Port", "8080").(string)
	GinMode := configutil.ReadConfigKey(configFile, "System", "Gin", "Release").(string)

	if configutil.HasSection(configFile, "CloudCenter") {
		ginutil.AddUrl("/cloud/monitor", cloud.CloudMonitor, ginutil.POST, ginutil.GET) //注册监控事件(不能放到多线程)
		go cloud.RegistraCloud()                                                        //注册服务到注册中心
	}

	httpServer := ginutil.GetGin(GinMode, Root, Port, appKey, interceptorFunc)

	fmt.Println(stringutil.Append("================ ", Title, Name, "启动,使用端口:", Port, ",时间:", time.Now().Format("2006-01-02 15:04:05"), " ================"))

	if err := httpServer.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
		if errors.Is(err, http.ErrServerClosed) {
			Log.Error("服务关闭")
			return
		}

		Log.Error("启动服务发生异常: ", err)
	}

}

// 初始化主数据库
func initMainDb(configFile string, dbOpenFun func(dsn string) gorm.Dialector) {
	bl, msg, res := configutil.GetSection(configFile, "DataSource")
	if !bl {
		Log.Error("获取数据库配置失败: ", msg)
		os.Exit(1)
		return
	}

	dataSource := res.(*ini.Section)

	dataSourceInfo := gormutil.DataSourceInfo{}

	if value, err := dataSource.GetKey("Type"); err == nil {
		dataSourceInfo.Type = value.String()
	}

	if value, err := dataSource.GetKey("User"); err == nil {
		dataSourceInfo.User = value.String()
	}

	if value, err := dataSource.GetKey("Pass"); err == nil {
		pass := value.String()
		if len(pass) > 3 && strings.HasPrefix(pass, "${") && strings.HasSuffix(pass, "}") {
			passKey := dataSourceInfo.PassKey
			if len(passKey) == 0 {
				passKey = "bricks"
			}

			pass = aesutil.Decrypt(pass[2:len(pass)-1], passKey)
		}

		dataSourceInfo.Pass = pass
	}

	if value, err := dataSource.GetKey("Ip"); err == nil {
		dataSourceInfo.Ip = value.String()
	}

	if value, err := dataSource.GetKey("Port"); err == nil {
		dataSourceInfo.Port = value.String()
	}

	if value, err := dataSource.GetKey("MainDb"); err == nil {
		dataSourceInfo.DbName = value.String()
	}

	if value, err := dataSource.GetKey("PrintSql"); err == nil {
		tmp, _ := value.Int()
		dataSourceInfo.PrintSql = tmp == 1
	}

	if value, err := dataSource.GetKey("AutoMigrate"); err == nil {
		tmp, _ := value.Int()
		dataSourceInfo.AutoMigrate = tmp == 1
	}

	bl, msg, res = gormutil.NewDb(dataSourceInfo, dbOpenFun)
	if !bl {
		Log.Error("连接数据库失败: ", msg)
		os.Exit(1)
		return
	}

	gormutil.AddGorm(gormutil.GormInfo{
		Type:   dataSourceInfo.Type,
		Name:   dataSourceInfo.DbName,
		GormDb: res.(*gorm.DB),
	}) //加入SQL工厂
}
